/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
* ListUtil.java
*
* Created on November 8, 2007, 9:15 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
 */
package javautil.collections;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.Vector;

/**
 *
 * @author stewari1
 */
public class ListUtil {

    public static void main(String[] args) {

        int[] array        = { 1, 2 };
        List<Integer> list = createArrayList(ArrayUtil.getIntegerArray(array));
        Integer[] intArray = create1dArray(list, Integer.class);

        System.out.println(intArray[0]);
    }

    public static int[] vector1DToInt1D(Vector vector) {

        int[] result = new int[vector.size()];

        for (int i = 0; i < result.length; i++) {

            result[i] = ((Integer) vector.get(i)).intValue();
        }

        return result;
    }

    /**
     * returns frequency of <CODE>obj</CODE> in the <CODE>list</CODE>
     */
    public static int getFreq(List list, Object obj) {

        int count = 0;

        for (Object tempObj : list) {

            if (tempObj.equals(obj)) {
                count++;
            }
        }

        return count;
    }

    public static List<Integer> getIndexList(List list, Object obj) {

        List<Integer> indexList = new ArrayList<>();

        for (int index = 0; index < list.size(); index++) {

            if (obj.equals(list.get(index))) {
                indexList.add(new Integer(index));
            }
        }

        return indexList;
    }

    public static <T> List<T> createArrayList(T[] array) {

        List<T> list = new ArrayList<>(array.length);

        for (T t : array) {

            list.add(t);
        }

        return list;
    }

    /**
     *
     * @param array
     * @return
     */
    public static <T> List<List<T>> createArrayList(T[][] array) {

        List<List<T>> list = new ArrayList<>(array.length);

        for (T[] t : array) {

            list.add(createArrayList(t));
        }

        return list;
    }

    /**
     * Method description
     *
     * @param list description
     * @param clazz description
     * @param <T> description
     *
     * @return description
     */
    @SuppressWarnings("unchecked")
    private static <T> T[] create1dArray(List<? extends T> list, Class<T> clazz) {

        T[] array1d = (T[]) Array.newInstance(clazz, list.size());

        array1d = list.toArray(array1d);

        return array1d;
    }

    @SuppressWarnings("unchecked")
    public static <T> T[][] create2dArray(List<? extends List<? extends T>> list, Class<T> clazz) {

        T[][] array2d = (T[][]) newArray(clazz, 2, list.size());

        for (int i = 0; i < list.size(); i++) {

            array2d[i] = create1dArray(list.get(i), clazz);
        }

        return array2d;
    }

    /**
     * Method description
     *
     * @param clazz description
     * @param arrayDimension description
     * @param size description
     * @param <T> description
     *
     * @return description
     */
    private static <T> Object newArray(Class<T> clazz, int arrayDimension, int size) {

        if (arrayDimension < 1) {
            throw new IllegalArgumentException("Array must have at least 1 dimension.");
        }

        return Array.newInstance(arrayElementClass(clazz, arrayDimension - 1), size);
    }

    /**
     * Method description
     *
     * @param clazz description
     * @param subarrayDimension description
     * @param <T> description
     *
     * @return description
     */
    private static <T> Class<?> arrayElementClass(Class<T> clazz, int subarrayDimension) {

        Class<?> result = clazz;

        while (subarrayDimension > 0) {

            result = Array.newInstance(result, 0).getClass();

            subarrayDimension--;
        }

        return result;
    }
}
